import amqp, { Connection, Channel, ConsumeMessage } from 'amqplib';
import { eventEmitter } from '../sse/EventEmitter';

/**
 * MQ 配置接口
 */
export interface MQConfig {
  hostname: string;
  port: number;
  username: string;
  password: string;
  vhost?: string;
  protocol?: string;
}

/**
 * 服务端 MQ 服务类
 * 负责在后端连接 RabbitMQ，接收消息，并通过 SSE EventEmitter 转发到前端
 */
export class ServerMQService {
  private static instance: ServerMQService;
  private config: MQConfig | null = null;
  private connection: any = null;
  private channel: any = null;
  private isConnected = false;

  private constructor() {}

  /**
   * 获取单例实例
   */
  public static getInstance(): ServerMQService {
    if (!ServerMQService.instance) {
      ServerMQService.instance = new ServerMQService();
    }
    return ServerMQService.instance;
  }

  /**
   * 初始化配置
   */
  public init(config: MQConfig) {
    this.config = config;
    console.log('🔧 MQ-Server: 配置已初始化');
  }

  /**
   * 连接到 RabbitMQ
   */
  public async connect(): Promise<void> {
    if (this.isConnected) {
      console.log('ℹ️ MQ-Server: 已连接，无需重复操作');
      return;
    }

    if (!this.config) {
      console.error('❌ MQ-Server: 配置未初始化，无法连接');
      throw new Error('MQ config is not initialized.');
    }

    try {
      const { hostname, port, username, password, vhost, protocol } = this.config;
      const connUrl = `${protocol || 'amqplib'}://${username}:${password}@${hostname}:${port}${vhost ? '/' + vhost : ''}`;
      
      console.log(`🔄 MQ-Server: 正在连接到 ${hostname}...`);
      this.connection = await amqp.connect(connUrl);
      this.isConnected = true;
      console.log('✅ MQ-Server: RabbitMQ 连接成功');

      this.connection.on('error', (err: any) => {
        console.error('❌ MQ-Server: 连接出错', err);
        this.isConnected = false;
      });

      this.connection.on('close', () => {
        console.warn('⚠️ MQ-Server: 连接已关闭，尝试重连...');
        this.isConnected = false;
        setTimeout(() => this.connect(), 5000); // 5秒后重连
      });

      this.channel = await this.connection.createChannel();
      console.log('✅ MQ-Server: 通道创建成功');

      await this.setupListeners();

    } catch (error) {
      console.error('❌ MQ-Server: RabbitMQ 连接失败', error);
      this.isConnected = false;
      console.log('🔄 MQ-Server: 5秒后尝试重连...');
      setTimeout(() => this.connect(), 5000);
    }
  }

  /**
   * 设置消息监听
   */
  private async setupListeners(): Promise<void> {
    if (!this.channel) {
      console.error('❌ MQ-Server: 通道未创建，无法设置监听器');
      return;
    }

    try {
      const exchange = 'warning_exchange';
      const routingKey = 'warning.#'; // 监听所有以 "warning." 开头的路由键

      await this.channel.assertExchange(exchange, 'topic', { durable: true });

      // 声明一个独占的、自动删除的、由服务器命名的队列
      // 传递空字符串会让 RabbitMQ 生成一个唯一的队列名
      const q = await this.channel.assertQueue('', { exclusive: true });
      await this.channel.bindQueue(q.queue, exchange, routingKey);
      this.channel.consume(q.queue, (msg: ConsumeMessage | null) => {
        if (msg) {
          this.handleMessage(msg);
          this.channel?.ack(msg);
        }
      });

    } catch (error) {
      console.error('❌ MQ-Server: 设置监听器失败', error);
    }
  }

  /**
   * 处理收到的消息
   */
  private handleMessage(msg: ConsumeMessage | null): void {
    if (!msg) {
      return;
    }
    try {
      const routingKey = msg.fields.routingKey;
      const messageContent = msg.content.toString();
      const messageData = JSON.parse(messageContent);
      if(messageData.orgPath.length > 0){
        const routingKey = "warning."+messageData.orgPath.join('.');
        eventEmitter.emit(routingKey, messageData.type || 'message', messageData);
      }
      

    //   // 从路由键中提取频道信息，并进行层级化事件发布
      // const parts = routingKey.split('_');
      // if (parts.length > 1) {
      //   // parts.slice(1) 移除了 "warning" 和最后的设备ID和事件类型
      //   const channelParts = parts.slice(0, -2); 
      //   let currentChannel = '';

      //   // 例如: routingKey = "warning.city.county.street"
      //   // channelParts = ["city", "county", "street"]
      //   // 会依次发布事件到频道 "city", "city_county", "city_county_street"
      //   for (const part of channelParts) {
      //     currentChannel = currentChannel ? `${currentChannel}_${part}` : part;
      //     console.log(`🚀 MQ-Server: 转发消息到 SSE 频道: ${currentChannel}`);
      //     eventEmitter.emit(currentChannel, messageData.type || 'message', messageData);
      //   }
      // } else {
      //   console.warn(`⚠️ MQ-Server: 无法从路由键 ${routingKey} 中提取有效频道`);
      // }

    } catch (error) {
      console.error('❌ MQ-Server: 处理消息失败', error);
    }
  }

  /**
   * 断开连接
   */
  public async disconnect(): Promise<void> {
    try {
      if (this.channel) {
        await this.channel.close();
      }
      if (this.connection) {
        await this.connection.close();
      }
      this.isConnected = false;
      console.log('✅ MQ-Server: 连接已成功断开');
    } catch (error) {
      console.error('❌ MQ-Server: 断开连接失败', error);
    }
  }
}

export const serverMQService = ServerMQService.getInstance(); 